﻿using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using System.Reflection;
using System.ComponentModel;
using System.Security;
using System.Security.Permissions;

using PickGold.Util;

namespace PickGold.Web.Controls
{
	/// <summary>
	/// 循环数据源。
	/// </summary>
	[ControlBuilder(typeof(Builder))]
	[ToolboxData("<{0}:CyclicDataSource runat=\"server\" />")]
	[ParseChildren(true)]
	[PersistChildren(false)]
	public class CyclicDataSource : DataSourceControl
	{
		class V : DataSourceView
		{
			public V(CyclicDataSource source) : base(source, string.Empty)
			{
				this.Source = source;
			}

			protected override IEnumerable ExecuteSelect(DataSourceSelectArguments arguments)
			{
				if (this.Source == null)
					return null;

				var c = new int[1];
				var e = CyclicDataSource.ExecuteSelect(this.Source._Values, this.Source._Value, this.Source._Cyclic, arguments.StartRowIndex, arguments.MaximumRows, c);
				arguments.TotalRowCount = c[0];
				return e;
			}
			/// <summary>
			/// CyclicDataSource
			/// </summary>
			public CyclicDataSource Source;
		}

		/// <summary>
		/// 循环次数
		/// </summary>
		[Bindable(true)]
		[DisplayName("循环次数")]
		[Description("循环次数，输出数字")]
		public int Cyclic
		{
			set
			{
				this._Cyclic = value;
			}
			get
			{
				return this._Cyclic;
			}
		}

		/// <summary>
		/// 按字数表示的循环次数
		/// </summary>
		[Bindable(true)]
		[DisplayName("按字数表示的循环次数")]
		[Description("按字数表示的循环次数，输出字符")]
		public string Value
		{
			set
			{
				this._Value = value;
			}
			get
			{
				return this._Value;
			}
		}

		/// <summary>
		/// 按元素个数表示的循环次数
		/// </summary>
		[Bindable(true)]
		[DisplayName("按元素个数表示的循环次数")]
		[Description("按元素个数表示的循环次数，输出字符串")]
		[TypeConverter(typeof(StringArrayConverter))]
		public string[] Values
		{
			set
			{
				this._Values = value;
			}
			get
			{
				return this._Values;
			}
		}

		/// <summary>
		/// 获取与数据源控件关联的命名的数据源视图。
		/// </summary>
		/// <param name="viewName">要检索的 System.Web.UI.DataSourceView 的名称。在只支持一个视图的数据源控件（如 System.Web.UI.WebControls.SqlDataSource）中，此参数会被忽略。</param>
		/// <returns>返回与 System.Web.UI.DataSourceControl 关联的指定 System.Web.UI.DataSourceView。</returns>
		protected override DataSourceView GetView(string viewName)
		{
			return new V(this);
		}

		/// <summary>
		/// 循环数据枚举
		/// </summary>
		/// <param name="values">按元素个数表示的循环次数</param>
		/// <param name="value">按字数表示的循环次数</param>
		/// <param name="cyclic">循环次数</param>
		/// <param name="index">输出的索引位置</param>
		/// <param name="length">输出最大数量</param>
		/// <param name="count">可输出总数</param>
		/// <returns>输出枚举</returns>
		public static IEnumerable ExecuteSelect(string[] values, string value, int cyclic, int index, int length, int[] count)
		{
			var d = values;
			var v = value;
			var c = cyclic;
			var l = c;
			var s = c;
			var e = c;
			if (d != null)
			{
				l = d.Length;
				if (s < 0)
					s *= -1;
				if (s > 0)
				{
					if (s <= l)
						v = d[s - 1];
					else
						v = d[l - 1];
				}
				if (c > 0)
					c = 0;
				else
					c = s;
			}
			if (v != null)
			{
				if (c < 0)
				{
					c *= -1;
					d = v.Substring(c).Split(new string[] { v.Remove(c), }, StringSplitOptions.None);
					l = d.Length;
				}
				else if (c > 0)
				{
					d = new string[(v.Length + c - 1) / c];
					for (l = d.Length - 1; l >= 0; l--)
					{
						if (l * c + c > v.Length)
							d[l] = v.Substring(l * c);
						else
							d[l] = v.Substring(l * c, c);
					}
					l = d.Length;
				}
				else
				{
					l = v.Length;
				}
			}
			s = index;
			e = length;
			if (e <= 0 || e + s > l)
				e = l;
			else
				e += s;
			for (; s < e; s++)
			{
				if (d != null)
					yield return d[s];
				else if (v != null)
					yield return v[s];
				else
					yield return s;
			}
			if (count != null && count.Length > 0)
				count[0] = l;
			count = null;
		}

		private int _Cyclic;
		private string _Value;
		private string[] _Values;
	}
}
